package com.mgq.algorithm.bit;

/**
 * 位运算实现算术运算
 */
public class Arithmetic {
    /**
     * 加法运算
     * 2个数相加,等同于 2个数无进位相加和进位相加的结果, 一直加到没有进位
     * ^异或 表示无进位相加
     * &<<1 表示进位结果
     * 例如:
     * 13:   0 1 1 0 1
     * 7 :   0 0 1 1 1  相加
     * ----  --------------
     * ^     0 1 0 1 0
     * &<<1  0 1 0 1 0  相加
     * --------------------
     * ^     0 0 0 0 0
     * &&<<1 1 0 1 0 0
     * ---------------- 无进位了
     * ^     1 0 1 0 0
     * &&<<1 0 0 0 0 0 无进位了,就返回结果
     *
     * @param a
     * @param b
     * @return
     */
    public static int add(int a, int b) {
        int sum = 0;
        if (b == 0) {
            return a;
        }
        while (b != 0) {
            sum = a ^ b;
            b = (a & b) << 1;
            a = sum;
        }
        return sum;
    }

    /**
     * 减法 a-b=a+(-b)
     * b求负数是 取反再加1
     *
     * @param a
     * @param b
     * @return
     */
    public static int minus(int a, int b) {
        return add(a, negNum(b));
    }

    /**
     * 不能用算术运算符, 所以就 add(~n, 1)  等价于 (~b)+1
     *
     * @param n
     * @return
     */
    public static int negNum(int n) {
        return add(~n, 1); //等价于 (~b)+1
    }

    /**
     * 乘法
     * 就相当于我们的乘法运算.
     *例如:
     * a      0 1 1 0 1        13
     * b      0 1 1 1 0        14
     * -------------------
     *        0 0 0 0 0
     *      0 1 1 0 1
     *    0 1 1 0 1
     *  0 1 1 0 1
     *0 0 0 0 0
     *--------------------
     *0 1 0 1 1 0 1 1 0        182
     * @param a
     * @param b
     * @return
     */
    public static int multi(int a, int b) {
        int res = 0;
        while (b != 0) {
            //b!=0
            if ((b & 1) != 0) {
                res = add(res, a);
            }
            //a向左走, b向右走
            a <<= 1;
            //a = a << 1;
            b >>>= 1;
            // b = b >>> 1;
        }
        return res;
    }


    public static void main(String[] args) {
        System.out.println(add(5, 3));
        System.out.println(minus(5, 3));
        System.out.println(multi(5, 3));
    }
}
